function [TrueList] = Ddavid_recover_single_label_SVDDandKNN(Data, TrueLabel, SampledTrueLabel, K, KNNList, R, T)

% [TrueList] = Ddavid_recover_single_label_SVDDandKNN(Data, TrueLabel, SampledTrueLabel, K, KNNList, R, T)
%
% TightSVDD -> Loop(KNN & SVDD)
%
% <Input>
% Data: [n*m], n is the number of instances, m is the number of features
% TrueLabel: [n*1], the value is {-1, 1}, the real answer of this label
% SampledTrueLabel: [n*1], the value is {-1, 1}, the sampled label
% K: The K value of KNN
% KNNList: The KNN List (for saving time)
% R: double, the relaxation parameter, R >= 0
% T: integer, the max relaxation times
%
% <Output>
% TrueList: [n*1], the value is {0, 1}

disp(['Ddavid_recover_single_label_SVDDandKNN R = ' num2str(R)]);

ArgMax = 1.0;

[~, ArgCurrent, CurrentTrueList] = Ddavid_find_tightest_svdd(Data, SampledTrueLabel, R);

% Loop SVDD and KNN to add points

CurrentT = 0;
ArgCurrent = ArgCurrent * 2;

while (ArgCurrent <= ArgMax)
    % Record the number of True points before KNN + SVDD
    CurrentN = sum(CurrentTrueList == 1);

    % KNN
    KNNAddList = Ddavid_add_points_by_knn(TrueLabel, CurrentTrueList, K, KNNList);
    KNNAddList = (KNNAddList == 1) & (CurrentTrueList == 0);

    % SVDD
    [~, SVDDAddList] = Ddavid_add_points_by_svdd(Data, TrueLabel, CurrentTrueList, ArgCurrent);
    SVDDAddList = (SVDDAddList == 1) & (CurrentTrueList == 0);
    
    % KNN & SVDD
    AddedLabel = (KNNAddList == 1) & (SVDDAddList == 1);
    CurrentTrueList = CurrentTrueList | AddedLabel;
    
    % Show the accuracy of added points
    if(sum(AddedLabel) > 0)
        CorrectAddedLabel = (AddedLabel == 1) & (TrueLabel == 1);
        disp(['  KNN & SVDD Add ' num2str(sum(AddedLabel)) ' points, correct ' num2str(sum(CorrectAddedLabel)) ' points, ' num2str(sum(CorrectAddedLabel) / sum(AddedLabel) * 100) '%']);
    end
    
    % Record the number of True points after KNN & SVDD
    NextN = sum(CurrentTrueList == 1);

    if(NextN == CurrentN)
        if(CurrentT < T)
            CurrentT = CurrentT + 1;
            disp(['ArgCurrent = ' num2str(ArgCurrent) ' -> ' num2str(ArgCurrent * 2)]);
            ArgCurrent = ArgCurrent * 2;
        else
            disp('  break by KNN & SVDD');
            break;
        end
    end
end

TrueList = zeros(size(SampledTrueLabel, 1), 1);
TrueList(CurrentTrueList == 1) = 1;
TrueList(CurrentTrueList == 0) = -1;
